package com.jilijili.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.jilijili.config.mq.RabbitMQConfig;
import com.jilijili.enums.MessageEnum;
import com.jilijili.exceptions.GraceException;
import com.jilijili.grace.result.ResponseStatusEnum;
import com.jilijili.mapper.CommentMapper;
import com.jilijili.mapper.CommentMapperCustom;
import com.jilijili.pojo.Comment;
import com.jilijili.pojo.Users;
import com.jilijili.pojo.Vlog;
import com.jilijili.pojo.bo.CommentBo;
import com.jilijili.pojo.mo.MessageMo;
import com.jilijili.pojo.vo.CommentVo;
import com.jilijili.service.CommentService;
import com.jilijili.service.MsgService;
import com.jilijili.service.VlogService;
import com.jilijili.service.base.BaseInfoProperties;
import com.jilijili.service.base.PagedGridResult;
import com.jilijili.utils.redis.RedisOperator;
import org.n3r.idworker.Sid;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author admin
 * @description 针对表【comment(评论表)】的数据库操作Service实现
 * @createDate 2022-03-12 07:11:29
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment>
        implements CommentService {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private CommentMapper commentMapper;

    @Resource
    private CommentMapperCustom commentMapperCustom;

    @Resource
    private MsgService msgService;

    @Resource
    private VlogService vlogService;

    @Resource
    private Sid sid;

    @Resource
    private RedisOperator redis;


    /**
     * 取消评论点赞
     *
     * @param userId    喜欢这条评论的用户
     * @param commentId 喜欢的评论
     */
    @Override
    public void unlikeComment(String userId, String commentId) {
        if (StringUtils.isBlank(userId) && StringUtils.isBlank(commentId)) {
            GraceException.display(ResponseStatusEnum.FAILED);
        }
        this.redis.decrementHash(BaseInfoProperties.REDIS_VLOG_COMMENT_LIKED_COUNTS + ":" + commentId, commentId, 1);
        this.redis.hdel(BaseInfoProperties.REDIS_USER_LIKE_COMMENT, userId + ":" + commentId);
    }

    /**
     * @param userId    喜欢这条评论的用户
     * @param commentId 喜欢的评论
     */
    @Override
    public void likeComment(String userId, String commentId) {
        if (StringUtils.isBlank(userId) && StringUtils.isBlank(commentId)) {
            GraceException.display(ResponseStatusEnum.FAILED);
        }
        this.redis.incrementHash(BaseInfoProperties.REDIS_VLOG_COMMENT_LIKED_COUNTS + ":" + commentId, commentId, 1);
        this.redis.setHashValue(BaseInfoProperties.REDIS_USER_LIKE_COMMENT, userId + ":" + commentId, "1");

        //TODO 系统消息
        Comment comment = this.commentMapper.selectById(commentId);
        Vlog vlog = this.vlogService.getById(comment.getVlogId());
        Map<String, Object> map = new HashMap<>();
        map.put("vlogId", comment.getVlogId());
        map.put("vlogCover", vlog.getCover());
        map.put("commentId", commentId);
        this.msgService.createMsg(
                userId,
                comment.getCommentUserId(),
                MessageEnum.LIKE_COMMENT.type,
                map);

    }

    /**
     * 删除评论
     *
     * @param commentUserId 发表评论的用户id
     * @param commentId     这条评论的id
     * @param vlogId        对视频的id
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    @Override
    public void deleteComment(String commentUserId,
                              String commentId,
                              String vlogId) {
        Comment comment = new Comment();
        comment.setId(commentId);
        comment.setCommentUserId(commentUserId);
        comment.setVlogId(vlogId);

        // TODO 删除评论操作
        int i = this.commentMapper.deleteById(comment);
        if (i <= 0) {
            GraceException.display(ResponseStatusEnum.FAILED);
        }

        // TODO 评论总数的累减
        this.redis.decrement(BaseInfoProperties.REDIS_VLOG_COMMENT_COUNTS + ":" + vlogId, 1);


    }

    /**
     * 查询评论
     *
     * @param vlogId
     * @return
     */
    @Override
    public PagedGridResult queryCommentByVlodIdList(String vlogId, String userId, Integer page, Integer pageSize) {
        IPage<CommentVo> commentVoIPage = this.commentMapper.selectJoinPage(new Page<>(page, pageSize), CommentVo.class,
                new MPJLambdaWrapper<CommentVo>()
                        .selectAs(Comment::getId, CommentVo::getCommentId)
                        .selectAs(Comment::getVlogId, CommentVo::getVlogId)
                        .selectAs(Comment::getFatherCommentId, CommentVo::getFatherCommentId)
                        .selectAs(Comment::getCommentUserId, CommentVo::getCommentUserId)
                        .selectAs(Comment::getContent, CommentVo::getContent)
                        .selectAs(Users::getId, CommentVo::getVlogerId)
                        .selectAs(Users::getNickname, CommentVo::getCommentUserNickname)
                        .selectAs(Users::getFace, CommentVo::getCommentUserFace)
                        .leftJoin(Users.class, Users::getId, Comment::getCommentUserId)
                        .eq(Comment::getVlogId, vlogId).orderBy(true, false, Comment::getCreateTime, Comment::getLikeCounts));

        List<CommentVo> opoert = opoert(userId, commentVoIPage);
        commentVoIPage.setRecords(opoert);

      /*  Map<String, Object> map = new HashMap<String, Object>();
        map.put("vlogId", vlogId);
        List<CommentVo> commentVoList = commentMapperCustom.queryCommentByVlodIdList(map);
        IPage<CommentVo> pageList = new Page<CommentVo>(page,pageSize);*/
        PagedGridResult pagedGridResult = new PagedGridResult();
        pagedGridResult.setRows(commentVoIPage.getRecords());
        pagedGridResult.setPage((int) commentVoIPage.getCurrent());
        pagedGridResult.setTotal(commentVoIPage.getPages());
        pagedGridResult.setRecords(commentVoIPage.getTotal());
        return pagedGridResult;
    }

    private List<CommentVo> opoert(String userId, IPage<CommentVo> commentVoIPage) {
        List<CommentVo> records = commentVoIPage.getRecords();
        for (CommentVo commentVo : records) {
            String commentId = commentVo.getCommentId();
            // 当前短视频的某评论的点赞总数
            String countStr = String.valueOf(this.redis.getRedisTemplate()
                    .opsForHash()
                    .get(BaseInfoProperties.REDIS_VLOG_COMMENT_LIKED_COUNTS + ":" + commentId, commentId));

//            String countStr = this.redis.getHashValue(BaseInfoProperties.REDIS_VLOG_COMMENT_LIKED_COUNTS + ":" + commentId, commentId);
            Integer counsts = 0;
            if (StringUtils.isNotBlank(countStr) && !countStr.equalsIgnoreCase("null")) {
                counsts = Integer.valueOf(countStr);
            }
            commentVo.setLikeCounts(counsts);

            // 判断用户是否点赞该评论
            String doIlike = this.redis.hget(BaseInfoProperties.REDIS_USER_LIKE_COMMENT, userId + ":" + commentId);
            if (StringUtils.isNotBlank(doIlike) && "1".equalsIgnoreCase(doIlike)) {
                commentVo.setIsLike(1);
            }

            //判断这条评论是回复信息
//            this.this.commentMapper.selectById()
        }
        return records;
    }

    /**
     * 发表评论
     *
     * @param commentBo
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    @Override
    public CommentVo createComment(CommentBo commentBo) {
        Comment comment = CommentBo.convertComment(commentBo);
        comment.setId(this.sid.nextShort());
        comment.setLikeCounts(0);
        comment.setCreateTime(LocalDateTime.now());

        //TODO 累加操作
        int isInsert = this.commentMapper.insert(comment);
        if (isInsert <= 0) {
            GraceException.display(ResponseStatusEnum.FAILED);
        }
        //TODO 评论中总数累加
        redis.increment(BaseInfoProperties.REDIS_VLOG_COMMENT_COUNTS + ":" + comment.getVlogId(), 1);

        // 返回最新的评论
        CommentVo commentVo = CommentVo.convertCommentVo(comment);


        //TODO 创建评论消息,发送队列,异步解耦
        Map<String, Object> map = new HashMap<>();
        Vlog vlog = this.vlogService.getById(commentBo.getVlogId());
        map.put("vlogId", vlog.getId());
        map.put("vlogCover", vlog.getCover());
        map.put("commentId", comment.getId());
        map.put("commentContent", commentBo.getContent());

        Integer type = MessageEnum.COMMENT_Qg.type;
        String routKey = MessageEnum.COMMENT_Qg.enValue;
        if (StringUtils.isNotBlank(commentBo.getFatherCommentId()) &&
                !commentBo.getFatherCommentId().equalsIgnoreCase("0")) {
            type = MessageEnum.REPLY_YOU.type;
            routKey = MessageEnum.REPLY_YOU.enValue;
        }

        String jsonString = JSON.toJSONString(
                MessageMo.builder()
                        .fromUserId(commentBo.getCommentUserId())
                        .toUserId(commentBo.getVlogerId())
                        .msgType(type)
                        .msgContent(map).build());
        this.rabbitTemplate.convertAndSend(
                RabbitMQConfig.EXCHANGE_MSG,
                "routing.sys.msg." + routKey,
                jsonString);
        /*this.msgService.createMsg(
                commentBo.getCommentUserId(), // 评论用户
                commentBo.getVlogerId(), // 被评论的视屏用户
                type, // 消息类型
                map); // 消息内容*/
        return commentVo;
    }


}




